const { Transform } = require('stream');
const moment = require('moment');
const _ = require('lodash');
const utils = require('../../utils');
let executablePath = 'C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe';

function getCookies(url) {
  return new Promise(resolve => {
      require(/msedge/.test(executablePath) ? '../../../edge-cookies-secure.js' : 'chrome-cookies-secure').getCookies(url, 'puppeteer', function (err, cookies) {
          resolve(cookies);
      });
  });
}
async function parse(browser, {url, selector, prepares, hasCookie}) {
  const page = await browser.newPage();
  hasCookie && await page.setCookie(...await getCookies(url));
  await page.goto(url);
  if (prepares) {
    const list = prepares.split(';');
    for (const item of list) {
      const [el, v] = item.split(':');
      await page.waitForSelector(el);
      if (v === 'click') {
        await page.click(el);
      } else if (v !== undefined) {
        await page.type(el, v);
      }
    }
  }
  if (selector) {
    await page.waitForSelector(selector);
    await page.$(selector);
  }
  const html = await page.evaluate(() => document.body.innerHTML);
  await page.close();
  return { html };
}
module.exports = function ({ encoding = 'utf-8', inFormat, outFormat, executablePath: _executablePath } = {}) {
  let browser;
  _executablePath && (executablePath = _executablePath);
  require('puppeteer').launch({
    headless: true, // 开启界面
    devtools: false, // 开启调试
    executablePath,
  }).then(o=>{ browser = o });
  const stream = new Transform({ objectMode: true });
  inFormat = utils.parseFunction(inFormat);
  outFormat = utils.parseFunction(outFormat);
  const errorList = [];

  stream._transform = async function (chunk, _encoding, callback) {
    utils.debug('htmlTransform [chunk]:', chunk);
    const params = inFormat ? await inFormat(chunk, { _, moment, utils }) : chunk;
    !browser && await utils.until(() => browser);
    let r = await parse(browser, params);
    if (r.error) {
      errorList.push(chunk);
      callback();
      return;
    }
    let html = r.html;
    outFormat && (html = outFormat(html, { _, moment, utils, $$: chunk }));
    stream.push(html);
    callback();
  };
  stream.on('finish', function () {
    browser && browser.close();
    errorList.length && console.error('htmlTransform [error]:', errorList);
    utils.debug('htmlTransform [finish]');
  });

  return stream;
};